HTTP Live Streaming
#HLS
概要
HLS とは、Apple が 2009 年に提案したマルチメディアのストリーミング配信用プロトコル。HTTP ベースであり、HTTP Adaptive Streaming の一種としても説明される。
2009 年に Internet-Draft が公開され、その後数多くの実装が登場し、議論が重ねられてきた。2020 年現在は RFC 8216 として仕様が公開されており、ファイルのデータフォーマット, サーバ/クライアントのとるべきアクション について規定されている。
https://en.wikipedia.org/wiki/HTTP_Live_Streaming
RFC 8216 - HTTP Live Streaming - IETF Tools
概念
HLS のプロトコルを読み進めていく上で登場する概念について軽くまとめておく。
Multimedia Presentation
再生対象のマルチメディア
Praylist への URI で定義される
Playlist
Media Playlist か Master Playlist のどちらか
どちらも URI および タグ を含んだ UTF-8 テキストになる
拡張子は m3u8
https://gyazo.com/1af7df16fdae73f1b044026fef4510f4
Master Playlist
より複雑な表現を記述できる。Variant Stream の集合を提供する
Variant Stream
同一コンテンツの別バージョンのこと
異なるフォーマットや解像度、ビットレートでエンコードされたメディアの Media Playlist 群
Master Playlist 内で #EXT-X-STREAM-INF で記述される。対応する Rendition の集合と紐づけることができる。
ネットワーク状態に応じて、適切な Variant Stream に切り替えられることが望ましい。
Rendition
同一のコンテンツの代替バージョンのこと。例えば、以下のようなものがある。
単一の映像に対して、異なる言語の複数の音声
単一の音声に対して、異なるカメラアングルから撮影された複数の映像
ユーザ設定に応じて、適切な Rendition に切り替えられることが望ましい
Master Playlist 内で #EXT-X-MEDIA で記述される
https://gyazo.com/e9406ba2e7829bbe24112f990aba2d2f
Media Playlist
Media Segment のリストを保持する
Media Segment
連続で再生すると、Multimedia Presentation の再生と同義になる
1 つ以上のトラックをもち、映像、音声、音声が埋め込まれた映像、あるいはサブタイトルになる。
https://gyazo.com/906af95aaf0f9a7beee96b1cb23ee446
https://tools.ietf.org/html/rfc8216#section-2
Media Services Live: Ingest Users Guide (v4)
Rendition Groups Reference in AWS Elemental MediaPackage - AWS Elemental MediaPackage
タグ (WIP)
Master Playlist および Media Playlist には、タグを記述できる。このタグの主な用途は以下になる。
Playlist のグローバルなパラメータを定義する
Media Segments や Media Playlist に関する情報を定義する
基本のタグ
EXTM3U
そのファイルが Extended M3U プレイリストファイルであることを示す。Playlist の最初の行に 必ず 必要。
EXT-X-VERSION
その Playlist ファイルが準拠する HLS のプロトコルバージョンを記述する。プロトコルバージョン1以外でサポートされる記述を利用する場合には必須。プロトコルバージョンの詳細についは下記を参照。
https://developer.apple.com/documentation/http_live_streaming/about_the_ext-x-version_tag
Media Segment Tags
EXT-X-KEY
Media Segment が暗号化されている場合、それを復号化するための情報が格納される。このタグに付与できる属性は以下がある。
METHOD:
暗号化方法を示す。NONE, AES-128, SAMPLE-AES のいずれか
NONE は暗号化されていないことを示す
AES-128 は 128 bit のキーを用いた Advanced Encryption Standard による暗号化
IV
128bit の 16進数
KEYFORMAT
URI で示されたリソースないでキーがどのように表現されているかを定義する
Media Playlist Tags
EXT-X-TARGETDURATION
EXT-X-MEDIA-SEQUENCE
EXT-X-DISCONTINUITY-SEQUENCE
EXT-X-ENDLIST
EXT-X-PLAYLIST-TYPE
その Media Playlist について、提供元であるサーバが保証すべき可変性を記述する。EVENT もしくは VOD (Video On Demand) のどちらかをとり、EVENT の場合は、一部の変更、削除は許可されないが、末尾に Media segments が追加される可能性がある。VOD の場合は、変更してはいけない。このタグがない場合は、Playlist の変更は仕様 (仕様書 6.2.1) に従う (割愛)。
EXT-X-I-FRAMES-ONLY
Playlist 内の各 Media segments が単一の I-frame であることを表す。I-frame とは、他のフレームに依存せずエンコードされたビデオフレーム。
Master Playlist Tags
EXT-X-MEDIA, EXT-X-STREAM-INF
EXT-X-MEDIA は、Rendition を記述できるタグ。Rendition とは、同一のコンテンツに対する、複数の代替可能なバージョン のこと。例えば、同一の映像に対する、異なる言語の複数の音声や、同一の音声に対する、異なるアングルからの複数の映像などを記述できる。どれを選択するかは、クライアント側の設定によって決められるようになっているべき。
Rendition は、グループを形成することができる。例えば、同一の映像に対して、異なる言語の複数の音声と、異なる言語の複数の字幕があった場合、音声の Rendition Group と字幕の Rendition Group の2つが定義できる。EXT-X-MEDIA タグには、このグループを一意に識別する識別子として GROUP-ID がある。
また、Rendition 自体の種類も決まっており、そちらは TYPE 属性に記述できる。音声 (AUDIO), 映像 (VIDEO), 字幕 (SUBTITLE), CC (CLOSED-CAPTION) の4つがサポートされている。
Rendition Group は、この TYPE と GROUP-ID の組み合わせで一意に定められる。
その他にも、複数の Rendition のなかでどれをデフォルトとするか設定できる DEFAULT 属性や、Rendition 自体を一意に識別できる NAME 属性なども存在する。
一方、EXT-X-STREAM-INF は、Variant Stream を記述できるタグ。Variant Stream とは、同一コンテンツに対する、解像度やビットレート、フォーマットが異なる別のバージョン のこと。
下記は、EXT-X-MEDIA, EXT-X-STRAM-INF の例。
code:sample.m3u8
#EXTM3U
#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="audio",LANGUAGE="ja",NAME="日本語",AUTOSELECT=YES, DEFAULT=YES,URI="ja/prog_index.m3u8"
#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="audio",LANGUAGE="eng",NAME="English",AUTOSELECT=YES, DEFAULT=NO,URI="eng/prog_index.m3u8"
#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="audio",LANGUAGE="zh-Hans",NAME="中文",AUTOSELECT=YES, DEFAULT=NO,URI="fre/prog_index.m3u8"
#EXT-X-MEDIA:TYPE=SUBTITLES,GROUP-ID="vtt",LANGUAGE="ja",NAME="日本語",DEFAULT=YES,AUTOSELECT=YES,URI="ja/sub_index.m3u8"
#EXT-X-MEDIA:TYPE=SUBTITLES,GROUP-ID="vtt",LANGUAGE="en",NAME="English",DEFAULT=NO,AUTOSELECT=YES,URI="en/sub_index.m3u8",
#EXT-X-MEDIA:TYPE=SUBTITLES,GROUP-ID="vtt",LANGUAGE="zh-Hans",NAME="中文",DEFAULT=NO,AUTOSELECT=YES,URI="en/sub_index.m3u8"
#EXT-X-STREAM-INF:BANDWIDTH=140205,CODECS="mp4a.40.5,avc1.4d400c",RESOLUTION=256x144,FRAME-RATE=30,SUBTITLES="vtt",CLOSED-CAPTIONS=NONE,AUDIO="audio"
lo/prog_index.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=410170,CODECS="mp4a.40.2,avc1.4d401e",RESOLUTION=640x360,FRAME-RATE=30,SUBTITLES="vtt",CLOSED-CAPTIONS=NONE,AUDIO="audio"
mid/prog_index.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=920179,CODECS="mp4a.40.2,avc1.4d401f",RESOLUTION=1280x720,FRAME-RATE=30,SUBTITLES="vtt",CLOSED-CAPTIONS=NONE,AUDIO="audio"
hi/prog_index.m3u8
上記の Playlist には、以下のような Rendition および Variant Stream が含まれている。実際の再生時には、これらの組み合わせをネットワーク状態やユーザ設定に基づいて決定し、再生する。
table:Rendition
TYPE NAME
AUDIO 日本語
AUDIO English
AUDIO 中文
SUBTITLES 日本語
SUBTITLES English
SUBTITLES 中文
table:VariantStream
ビットレート 解像度
140205 256x144
410170 640x360
920179 1280x720
EXT-X-I-FRAME-STREAM-INF
EXT-X-SESSION-DATA
EXT-X-SESSION-KEY
Media もしくは Master Playlist
EXT-X-INDEPENDENT-SEGMENTS
EXT-X-START
サンプル
Media Playlist
下記が、Playlist (Media Playlist) の例。クライアントは、Playlist を再生するためには以下の手順をふむ。
1. Playlist を HTTP で DL
2. 各 Media segment を DL & 再生
3. Playlist は定期的にリロードする? (追加された segment がないか見つけるためのようだ)
code:Playlist
#EXTM3U <- フォーマットを識別するタグ
#EXT-X-TARGETDURATION:10 <- すべての Media Segment は 10 秒以下であることを示す
#EXTINF:9.009, <- これ以降は二行ごとに Media Segment
http://media.example.com/first.ts 一行目が再生時間、二行目がマルチメディア表現 = URI
#EXTINF:9.009,
http://media.example.com/second.ts
#EXTINF:3.003,
http://media.example.com/third.ts
https://developer.apple.com/streaming/HLS-WWDC-2017-Preliminary-Spec.pdf
Master Playlist
2018/09/17時点、Twitter の映像ファイルについてちょっと覗かせてもらうと、以下のような形式になっていた。
code:text
#EXTM3U
#EXT-X-INDEPENDENT-SEGMENTS
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=256000,RESOLUTION=320x180,CODECS="mp4a.40.2,avc1.4d0015"
/fuga/hoge.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=832000,RESOLUTION=640x360,CODECS="mp4a.40.2,avc1.4d001f"
/fuga/hoge.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=2176000,RESOLUTION=854x480,CODECS="mp4a.40.2,avc1.64001f"
/fuga/hoge.m3u8
EXT-X-STREAM-INF タグが利用されている。これは Variant Stream を示しており、Redition の集合が情報として付加されている。また、続く行には Media Playlist が示されている。
パラメータをみるに、異なるサイズ、bandwidth のための Media Playlist が列挙されているようだ。どのような場合にどの Redition が選択されるのかは今の所よくわからない。
また、URI には相対パスが指定されていた。Playlist 内の相対パスについては以下に記述されていた。URI が相対パスであった場合、それを含んだ Playlist に対する相対パスとしてみなされるようだ。
A URI in a Playlist, whether it is a URI line or part of a tag, MAY be relative. Any relative URI is considered to be relative to the URI of the Playlist that contains it.
https://tools.ietf.org/html/rfc8216#section-4.1
しかし、Twitter の場合は https://video.twimg.com/ からの相対パスが記述されているようだった。
改めて MediaPlaylist を GET してみると、以下のようになっていた。
code:text
#EXTM3U
#EXT-X-VERSION:6
#EXT-X-MEDIA-SEQUENCE:0
#EXT-X-TARGETDURATION:3
#EXT-X-PLAYLIST-TYPE:VOD
#EXT-X-ALLOW-CACHE:YES
#EXTINF:3.000,
/hoge/fuga.ts
#EXTINF:3.000,
/hoge/fuga.ts
#EXTINF:3.000,
...
.ts という拡張子が出てきた。HLS でサポートされる拡張子は ここ に列挙されており、.ts はどうやら MPGE-2 Transport Streams 形式のファイルであるらしい。
その他
https://blogs.akamai.com/jp/2013/02/-1---http-live-streaminghls.html
http://telestreamblog.telestream.net/2017/05/what-is-abr/
https://www.slideshare.net/yuujihato/iosdc-2018-112400328